package com.abiao.shop.controller;

import com.abiao.shop.pojo.DiscountOrder;
import com.abiao.shop.pojo.User;
import com.abiao.shop.rabbitmq.SnapMQSender;
import com.abiao.shop.rabbitmq.SnapMessage;
import com.abiao.shop.redis.GoodsKey;
import com.abiao.shop.redis.RedisService;
import com.abiao.shop.result.CodeMsg;
import com.abiao.shop.result.Result;
import com.abiao.shop.service.GoodsService;
import com.abiao.shop.service.OrderService;
import com.abiao.shop.service.SnapService;
import com.abiao.shop.service.UserService;
import com.abiao.shop.vojo.GoodsVo;
import com.abiao.shop.vojo.OrderVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: snappedController 秒杀控制类
 * @Author: AB
 * @Date: 2021-07-17
 * @Version:v1.0
 */
@Slf4j
@Controller
@RequestMapping("/snap")
public class SnapController implements InitializingBean {
    @Autowired
    UserService userService;
    @Autowired
    GoodsService goodsService;
    @Autowired
    OrderService orderService;
    @Autowired
    SnapService snapService;
    @Autowired
    RedisService redisService;
    @Autowired
    SnapMQSender snapMQSender;

    Map<Long,Boolean> localOverMap = new HashMap<>();

    /**
     * 初始化时库存载入缓存
     */
    @Override
    public void afterPropertiesSet() {
        List<GoodsVo> list = goodsService.goodsVoList();
        if (list == null){
            return;
        }
        for (GoodsVo goodsVo:list){
            //商品库存存入缓存
            redisService.set(GoodsKey.getDiscountStock,""+goodsVo.getId(),goodsVo.getStockCount());
            localOverMap.put(goodsVo.getId(),false);
        }
    }

    //秒杀
    @RequestMapping("/do_snap")
    @ResponseBody
    public Result<?> snapGoods (Model model, User user, @RequestParam("goodsId") long goodsId){
        if (user == null){
            return Result.error(CodeMsg.LOGIN_LIMIT);
        }
        //内存标记，减少redis访问
        if (localOverMap.get(goodsId)){
            return Result.error(CodeMsg.STOCK_ZERO);
        }
        //redis预减库存
        long stock = redisService.decr(GoodsKey.getDiscountStock,""+goodsId);
        if (stock < 0){
            localOverMap.put(goodsId,true);
            return Result.error(CodeMsg.STOCK_ZERO);
        }
        //判断是否已经秒杀过了
        DiscountOrder orderRepeat = orderService.getDCOrderByGoodsIdUserIdInCache(user.getId(),goodsId);
        if (orderRepeat!=null){
            //重复秒杀
            return Result.error(CodeMsg.SNAP_REPEAT);
        }
        //加入消息队列
        SnapMessage message = new SnapMessage();
        message.setGoodsId(goodsId);
        message.setUser(user);
        snapMQSender.sendSnapMsg(message);
        //返回排队中
        return Result.success(CodeMsg.ON_QUEUE);

//        //判断库存
//        GoodsVo goodsVo = goodsService.getGoodsVoById(goodsId);
//        if (goodsVo.getStockCount()<=0){
//            //库存已卖光
//            return Result.error(CodeMsg.STOCK_ZERO);
//        }
//        //判断是否已经秒杀过了
//        DiscountOrder orderRepeat = orderService.getOrderByGoodsIdUserId(user.getId(),goodsId);
//        if (orderRepeat!=null){
//            //重复秒杀
//            return Result.error(CodeMsg.SNAP_REPEAT);
//        }
//        //减库存，下订单，写入秒杀订单
//        OrderVo orderVo = snapService.snapping(user,goodsVo);
//        return Result.success(orderVo);
    }

    //获取秒杀结果
    @RequestMapping("/result")
    @ResponseBody
    public Result<?> getResult(User user, @RequestParam("goodsId") long goodsId){
        Object obj = snapService.getSnapResult(user.getId(),goodsId);
        if (obj instanceof OrderVo){
            return Result.success((OrderVo)obj);
        }else {
            return Result.error((CodeMsg) obj);
        }

    }




}
